package com.central.apps.handler;

import cn.hutool.core.map.MapUtil;
import com.central.app.common.feign.WorkflowClient;
import com.central.app.common.util.BLuntil;
import com.central.app.service.HandlerService;
import com.central.apps.handler.base.LvBaseHandler;
import com.central.bizcommon.model.flow.FlowNode;
import com.central.bizcommon.model.flow.FlowOpinion;
import com.central.common.auth.details.LoginAppUser;
import com.central.common.util.SysUserUtil;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


@Log4j2
@Component
public class InspectionHandler extends LvBaseHandler {

    @Autowired
    private HandlerService handlerService;
    @Autowired
    private DataSourceTransactionManager transactionManager;
//    @Autowired
//    private com.central.apps.handler.dao.inspectionDao inspectionDao;
    @Autowired
    private WorkflowClient workflowClient;


    SimpleDateFormat sdftime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmm");
    SimpleDateFormat datefmt = new SimpleDateFormat("yyyy-MM-dd");

    public void timeTStartFlow(Long id, String app) {
        FlowOpinion flowOpinion = new FlowOpinion();
        flowOpinion.setOpId("admin");
        flowOpinion.setOpName("超级管理员");
        try {
            handlerService.forcibleStart(app, id, flowOpinion);
        } catch (Exception e) {
        }
    }

    /**
     * 操作工、点检员、维修工设置节点自定义审批人
     *
     * @param app
     * @param id
     * @param flowNode
     * @param vars
     * @return
     * @throws Exception
     */
    @Override
    public String addFlowCandidate(String app, Long id, FlowNode flowNode, Map<String, Object> vars) throws Exception {
        List<Map<String, Object>> defectreport = handlerService.findBySql("  select deptcode,inspectionstaffgroup,inspectionstaff,createuser from bl_inspection where id=" + id);
        String executer = "";
        String deptcode = MapUtil.getStr(defectreport.get(0), "deptcode");
        String area = MapUtil.getStr(defectreport.get(0), "area");

        String bc="";
        List<Map<String, Object>> personList = null;
        if (flowNode.getId().equals("czgsp")) {//操作工点检单（操作工审批）
            //获取设备排班表中当前日期当班的的字段名
            bc = BLuntil.getBjr();
            //查询当班包机人
            List<Map<String, Object>> list = handlerService.findBySql("  select inspectionassetnum from bl_inspectionline where inspectionnum in (  select inspectionnum from bl_inspection where id=" + id + ") order by id desc limit 1");
            String assetnum = MapUtils.getString(list.get(0), "inspectionassetnum");
            if(deptcode.equals("BL0301") || deptcode.equals("BL0302")|| deptcode.equals("BL0303")) {
                personList = handlerService.findBySql("   select concat_ws(',',equipmentperson1,equipmentperson2,equipmentperson3,  " +
                        "equipmentperson4,equipmentperson5,equipmentperson6,equipmentperson7,equipmentperson8,equipmentperson9,  " +
                        "equipmentperson10,equipmentperson11,equipmentperson12,equipmentperson13,equipmentperson14,equipmentperson15,  " +
                        "equipmentperson16,equipmentperson17,equipmentperson18,equipmentperson19,equipmentperson20) name from bl_asset where assetnum in (  " +
                        "    select inspectionassetnum from bl_inspectionline where inspectionnum in (  select inspectionnum from bl_inspection where id=" + id + ")) ");
//            }else if(deptcode.equals("BL0301") || deptcode.equals("BL0302")){
//                personList = handlerService.findBySql(" select "+bc+ " from bl_schedule where assetnum like '%"+assetnum+"%'");
            }else {
                SimpleDateFormat sf = new SimpleDateFormat("yyyy");
                SimpleDateFormat sf1 = new SimpleDateFormat("M");

                personList = handlerService.findBySql("  select personid name from bl_person where workgroup in (  select " + bc + " from bl_schedule where assetnum like '%"+assetnum+"%' and year ='"+sf.format(new Date())+"' and month ='"+sf1.format(new Date())+"') and personid in ( " +
                        "  select equipmentperson1  name from bl_asset  where assetnum='"+assetnum+"' union  " +
                        "  select equipmentperson2  name from bl_asset  where assetnum='"+assetnum+"' union " +
                        "  select equipmentperson3  name from bl_asset  where assetnum='"+assetnum+"' union " +
                        "  select equipmentperson4  name from bl_asset  where assetnum='"+assetnum+"' union " +
                        "  select equipmentperson5  name from bl_asset  where assetnum='"+assetnum+"' union " +
                        "  select equipmentperson6  name from bl_asset  where assetnum='"+assetnum+"' union " +
                        "  select equipmentperson7  name from bl_asset  where assetnum='"+assetnum+"' union " +
                        "  select equipmentperson8  name from bl_asset  where assetnum='"+assetnum+"' union " +
                        "  select equipmentperson9  name from bl_asset  where assetnum='"+assetnum+"' union " +
                        "  select equipmentperson10  name from bl_asset  where assetnum='"+assetnum+"' union " +
                        "  select equipmentperson11  name from bl_asset  where assetnum='"+assetnum+"' union " +
                        "  select equipmentperson12  name from bl_asset  where assetnum='"+assetnum+"' union " +
                        "  select equipmentperson13  name from bl_asset  where assetnum='"+assetnum+"' union " +
                        "  select equipmentperson14  name from bl_asset  where assetnum='"+assetnum+"' union " +
                        "  select equipmentperson15  name from bl_asset  where assetnum='"+assetnum+"' union " +
                        "  select equipmentperson16  name from bl_asset  where assetnum='"+assetnum+"' union " +
                        "  select equipmentperson17  name from bl_asset  where assetnum='"+assetnum+"' union " +
                        "  select equipmentperson18  name from bl_asset  where assetnum='"+assetnum+"' union " +
                        "  select equipmentperson19  name from bl_asset  where assetnum='"+assetnum+"' union " +
                        "  select equipmentperson20  name from bl_asset  where assetnum='"+assetnum+"' ) ");
            }

        }
        else if (flowNode.getId().equals("wxsp")) {//维修工点检（维修审批）
            personList = handlerService.findBySql("     select concat_ws(',',overhaulperson1,overhaulperson2,overhaulperson3,overhaulperson4) name" +
                    "  from bl_asset where assetnum in (  " +
                    "    select inspectionassetnum from bl_inspectionline where inspectionnum in (  select inspectionnum from bl_inspection where id=" + id + ")) ");
        }
        else if (flowNode.getId().equals("djzx")) {//点检员点检单（点检执行）
            personList = handlerService.findBySql("     select concat_ws(',',checkperson1,checkperson2,checkperson3,checkperson4) name " +
                    " from bl_asset where assetnum in (  " +
                    "    select inspectionassetnum from bl_inspectionline where inspectionnum in (  select inspectionnum from bl_inspection where id=" + id + ")) ");
        }

        if (CollectionUtils.isNotEmpty(personList)) {
//            if (flowNode.getId().equals("czgsp")){
//                //操作工点检人员来自设备排班表 不需要循环处理
//                executer=MapUtil.getStr(personList.get(0),"name");
//            }else {
//                //人员以逗号隔开
//                StringJoiner sj = new StringJoiner(",");
//                for (Map<String, Object> name : personList) {
//                    sj.add(MapUtils.getString(name, "name"));
//                }
//                executer = sj.toString();
//            }
            StringJoiner sj = new StringJoiner(",");
            for (int k = 0; k < personList.size(); k++) {
                Map<String, Object> name = personList.get(k);
                sj.add(MapUtils.getString(name, "name"));
            }
            executer = sj.toString();

        }
        if(executer==null || "".equals(executer)){
            executer="admin";
            log.info("没找到人进来了管理员");
        }
        return executer;
    }



    //点检员点检
    public void timeTaskToDjy(String date,int MINUTE) {
        List<Map<String, Object>> insAddList = new ArrayList<>();
        //根据点检标准查询点检员类型的id，点检周期和下次执行时间
        List<Map<String, Object>> lubricantsList = handlerService.findBySql("  select * from bl_inspectionstandard where isstart = 1 AND inspectiontype='点检员点检' " +
                " and spotstarttime<='" + date + "' and spotstarttime>DATE_SUB('" + date + "', INTERVAL " + MINUTE + " MINUTE) ");
        //执行判空操作
        if (lubricantsList != null) {
            for (int k = 0; k < lubricantsList.size(); k++) {
                Map<String, Object> lubMap = lubricantsList.get(k);
                String inspectorinspectioncycle = MapUtil.getStr(lubMap, "inspectorinspectioncycle");//点检员点检周期
                if ((null != inspectorinspectioncycle && inspectorinspectioncycle.equals("D")) ||
                        (null != inspectorinspectioncycle && inspectorinspectioncycle.equals("W") ||
                                (null != inspectorinspectioncycle && inspectorinspectioncycle.equals("M")))) {//如果维修工点检周期是天的话，下次执行时间与当前时间相同就推送
                    insAddList.add(lubMap);
                }
            }
        }
        timeTaskToInsDjy(insAddList, "djinspectionApp");
    }

    //点检员的更新周期方法
    public void timeTaskToInsDjy(List<Map<String, Object>> insAddList, String app) {
        //执行判空操作
        if (CollectionUtils.isNotEmpty(insAddList)) {
            //格式化日期
            String createtime = sdftime.format(new Date());

            //拿到所有新增的数据要启动流程
            StringJoiner sjNewNum = new StringJoiner("','","'","'");
            //拿到所有sql然后执行
            StringBuilder sbsql = new StringBuilder();

            for (int k = 0; k < insAddList.size(); k++) {
                //生成点检员点检编号   编号格式yyyyMMddHHmmss
                String newNum = "DJ"+fmt.format(new Date()) + String.format("%04d", k+1);
                System.out.println("编号" + newNum);
                Map lubteMap = insAddList.get(k);
                String insaddId = MapUtils.getString(lubteMap, "id");
                String insstdnum = MapUtil.getStr(lubteMap, "insstdnum");//点检员点检标准的编号
                String spotstarttime=MapUtil.getStr(lubteMap, "spotstarttime");//点检员下次开始时间
                Integer routinecheckcycleunit = MapUtil.getInt(lubteMap, "routinecheckcycleunit");//点检员点检周期单位
                String inspectorinspectioncycle = MapUtil.getStr(lubteMap, "inspectorinspectioncycle");//点检员点检周期
                sbsql.append("insert into bl_inspection(inspectorinspectioncycle,repairmaninspectioncycle,insstdnum,inspectionnum,inspectionname,inspectionroute,deptcode,inspectiontype,inspectiontool,keypart,inspectionstaffgroup,operatoninspectioncycle,operationstarttime,createuser,createtime,status,area) " +
                        "  select inspectorinspectioncycle,repairmaninspectioncycle,insstdnum,'" + newNum + "'as inspectionnum,insstdname as inspectionname,inspectionroute,deptcode,inspectiontype,inspectiontool,keypart,inspectionstaffgroup,operatoninspectioncycle,operationstarttime,'admin' AS createuser,'" + createtime + "' as createtime,'草稿' as status ,area from bl_inspectionstandard where id ='" + insaddId + "';");
                sjNewNum.add(newNum);

                String lublineSql = "insert into bl_inspectionline(isitabnormal,inspectionassetnum,inspectionassetname,part,inspectioncontent,inspectionstandard,inspectionmethod,operatingstatus,inspectionnum,createuser,createuserdesc,createtime,deptcode)";
                String lublineSql2 = "  select 0 , inspectionassetnum,inspectionassetname,part,inspectioncontent,inspectionstandard,inspectionmethod,operatingstatus,'" + newNum + "','1','超级管理员','" + createtime + "',deptcode from bl_inspectionstandardline where insstdnum = '" + insstdnum + "';";
                sbsql.append(lublineSql + lublineSql2);

                //维修工更新周期
                if (spotstarttime != null&& routinecheckcycleunit!=null) {
                    try {
                        Date starttime2 = sdftime.parse(spotstarttime);
                        if (null != inspectorinspectioncycle && inspectorinspectioncycle.equals("D")) {//更新点检周期为天的周期
                            Calendar cal = Calendar.getInstance();
                            cal.setTime(starttime2);
                            cal.add(Calendar.DAY_OF_WEEK,routinecheckcycleunit);
                            String Nextdate = sdftime.format(cal.getTime());
                            sbsql.append("update bl_inspectionstandard set spotstarttime=DATE_FORMAT('"+Nextdate+"','%Y-%m-%d %H:%i:%s') where id ='"+insaddId+"';");
                        } else if (null != inspectorinspectioncycle && inspectorinspectioncycle.equals("W")) {//更新点检周期为周的周期
                            Calendar cal = Calendar.getInstance();
                            cal.setTime(starttime2);
                            cal.add(Calendar.WEEK_OF_MONTH,routinecheckcycleunit);
                            String Nextdate = sdftime.format(cal.getTime());
                            sbsql.append("update bl_inspectionstandard set spotstarttime=DATE_FORMAT('"+Nextdate+"','%Y-%m-%d %H:%i:%s') where id ='"+insaddId +"';");
                        }else if (null != inspectorinspectioncycle && inspectorinspectioncycle.equals("M")) {//更新点检周期为月的周期
                            Calendar cal = Calendar.getInstance();
                            cal.setTime(starttime2);
                            cal.add(Calendar.MONTH,routinecheckcycleunit);
                            String Nextdate = sdftime.format(cal.getTime());
                            sbsql.append("update bl_inspectionstandard set spotstarttime=DATE_FORMAT('"+Nextdate+"','%Y-%m-%d %H:%i:%s') where id ='"+insaddId +"';");
                        }

                    } catch (ParseException e) {
                        e.printStackTrace();
                        String error_log = "insert into error_log(ywid,ywtype,message,createtime) values('"+insaddId+"','更新周期','"+"更新周期异常"+"','"+createtime+"');" ;
                        sbsql.append(error_log);
                    }
                }
            }
            //执行sql
            executeSql(sbsql);
            //执行流程
            executeFlow(sjNewNum, app);
        }
    }

    //维修工点检
    public void timeTaskToWxgdj(String date,int MINUTE) {
        List<Map<String, Object>> insAddList = new ArrayList<>();
        Map<String, Map<String, Object>> insListMap = MapUtil.newHashMap();
        //根据点检标准查询维修工类型的id，点检周期和下次执行时间
        List<Map<String, Object>> lubricantsList = handlerService.findBySql("  select * from bl_inspectionstandard where isstart = 1 AND inspectiontype='维修工点检' " +
                " and repairstarttime<='" + date + "' and repairstarttime>DATE_SUB('" + date + "', INTERVAL " + MINUTE + " MINUTE) ");
        log.info("查询维修工成功 进入判空");
        //执行判空操作
        if (lubricantsList != null) {
            for (int k = 0; k < lubricantsList.size(); k++) {
                Map<String, Object> lubMap = lubricantsList.get(k);
                String repairmaninspectioncycle = MapUtil.getStr(lubMap, "repairmaninspectioncycle");//维修工点检周期
                if ((null != repairmaninspectioncycle && repairmaninspectioncycle.equals("D")) ||
                        (null != repairmaninspectioncycle && repairmaninspectioncycle.equals("W") ||
                                (null != repairmaninspectioncycle && repairmaninspectioncycle.equals("M")))) {//如果维修工点检周期是天的话，下次执行时间与当前时间相同就推送
                    insAddList.add(lubMap);
                }
            }
        }
        log.info("操作成功维修工看一下多少需要执行下面的方法" + insAddList.size());
        timeTaskToInsWx(insAddList, "wxinspectionApp");
    }

    //维修工的更新周期方法
    public void timeTaskToInsWx(List<Map<String, Object>> insAddList, String app) {
        //执行判空操作
        if (CollectionUtils.isNotEmpty(insAddList)) {
            //格式化日期
            String createtime = sdftime.format(new Date());

            //拿到所有新增的数据要启动流程
            StringJoiner sjNewNum = new StringJoiner("','","'","'");
            //拿到所有sql然后执行
            StringBuilder sbsql = new StringBuilder();

            for (int k = 0,size = insAddList.size(); k < size; k++) {
                //获取到符合条件的维修工点检标准的id
                //生成维修工工点检编号   编号格式yyyyMMddHHmmss
                String newNum = "WX"+fmt.format(new Date()) + String.format("%04d", k+1);
                System.out.println("编号" + newNum);
                //根据维修工点检标准的id去查询对应的数据
                Map lubteMap = insAddList.get(k);
                String insaddId = MapUtils.getString(lubteMap, "id");
                String insstdnum = MapUtil.getStr(lubteMap, "insstdnum");//维修工点检标准的编号
                String repairstarttime=MapUtil.getStr(lubteMap, "repairstarttime");//维修工下次开始时间
                Integer maintenancecycleunit = MapUtil.getInt(lubteMap, "maintenancecycleunit");//维修工点检周期单位
                String repairmaninspectioncycle = MapUtil.getStr(lubteMap, "repairmaninspectioncycle");//维修工点检周期
                sbsql.append("insert into bl_inspection(inspectorinspectioncycle,repairmaninspectioncycle,insstdnum,inspectionnum,inspectionname,inspectionroute,deptcode,inspectiontype,inspectiontool,keypart,inspectionstaffgroup,operatoninspectioncycle,operationstarttime,createuser,createtime,status,area) " +
                        "  select inspectorinspectioncycle,repairmaninspectioncycle,insstdnum,'" + newNum + "'as inspectionnum,insstdname as inspectionname,inspectionroute,deptcode,inspectiontype,inspectiontool,keypart,inspectionstaffgroup,operatoninspectioncycle,operationstarttime,'1' AS createuser,'" + createtime + "' as createtime,'草稿' as status ,area from bl_inspectionstandard where id ='" + insaddId + "';");
                sjNewNum.add(newNum);

                String lublineSql = "insert into bl_inspectionline(isitabnormal,inspectionassetnum,inspectionassetname,part,inspectioncontent,inspectionstandard,inspectionmethod,operatingstatus,inspectionnum,createuser,createuserdesc,createtime,deptcode)";
                String lublineSql2 = "  select 0 , inspectionassetnum,inspectionassetname,part,inspectioncontent,inspectionstandard,inspectionmethod,operatingstatus,'" + newNum + "','1','超级管理员','" + createtime + "',deptcode from bl_inspectionstandardline where insstdnum = '" + insstdnum + "';";
                sbsql.append(lublineSql + lublineSql2);
                //维修工更新周期
                if (repairstarttime != null&&maintenancecycleunit!=null) {
                    try {
                        Date starttime2 = sdftime.parse(repairstarttime);
                        if (null != repairmaninspectioncycle && repairmaninspectioncycle.equals("D")) {//更新点检周期为天的周期
                            Calendar cal = Calendar.getInstance();
                            cal.setTime(starttime2);
                            cal.add(Calendar.DAY_OF_WEEK,maintenancecycleunit);
                            String Nextdate = sdftime.format(cal.getTime());
                            sbsql.append("update bl_inspectionstandard set repairstarttime=DATE_FORMAT('"+Nextdate+"','%Y-%m-%d %H:%i:%s') where id ='"+insaddId+"';");
                        } else if (null != repairmaninspectioncycle && repairmaninspectioncycle.equals("W")) {//更新点检周期为周的周期
                            Calendar cal = Calendar.getInstance();
                            cal.setTime(starttime2);
                            cal.add(Calendar.WEEK_OF_MONTH,maintenancecycleunit);
                            String Nextdate = sdftime.format(cal.getTime());
                            sbsql.append("update bl_inspectionstandard set repairstarttime=DATE_FORMAT('"+Nextdate+"','%Y-%m-%d %H:%i:%s') where id ='"+insaddId +"';");
                        }else if (null != repairmaninspectioncycle && repairmaninspectioncycle.equals("M")) {//更新点检周期为月的周期
                            Calendar cal = Calendar.getInstance();
                            cal.setTime(starttime2);
                            cal.add(Calendar.MONTH,maintenancecycleunit);
                            String Nextdate = sdftime.format(cal.getTime());
                            sbsql.append("update bl_inspectionstandard set repairstarttime=DATE_FORMAT('"+Nextdate+"','%Y-%m-%d %H:%i:%s') where id ='"+insaddId +"';");
                        }

                    } catch (ParseException e) {
                        e.printStackTrace();
                        String error_log = "insert into error_log(ywid,ywtype,message,createtime) values('"+insaddId+"','更新周期','"+"更新周期异常"+"','"+createtime+"');" ;
                        sbsql.append(error_log);
                    }
                }

            }

            //执行sql
            executeSql(sbsql);
            //执行流程
            executeFlow(sjNewNum, app);
        }
    }



    //操作工点检
    public void timeTaskToC(String date,int MINUTE) {
        List<Map<String, Object>> insAddList = new ArrayList<>();
        //根据点检标准查询操作工类型的id，点检周期，是否执行和早班，中班，晚班时间和下次执行时间
        List<Map<String, Object>> lubricantsList = handlerService.findBySql("  select * from bl_inspectionstandard where isstart = 1 AND inspectiontype='操作工点检' " +
                " and ((checkstarttime<='" + date + "' and checkstarttime>DATE_SUB('" + date + "', INTERVAL " + MINUTE + " MINUTE)) " +
                " or morningshifttime<='" + date + "' and morningshifttime>DATE_SUB('" + date + "', INTERVAL " + MINUTE + " MINUTE) " +
                " or middleshifttime<='" + date + "' and middleshifttime>DATE_SUB('" + date + "', INTERVAL " + MINUTE + " MINUTE) " +
                " or nightshifttime<='" + date + "' and nightshifttime>DATE_SUB('" + date + "', INTERVAL " + MINUTE + " MINUTE) " +
                ")");
        //执行判空操作
        if (lubricantsList .size()>0) {
            for (int k = 0; k < lubricantsList.size(); k++) {
                Map<String, Object> lubMap = lubricantsList.get(k);
                String operatoninspectioncycle = MapUtil.getStr(lubMap, "operatoninspectioncycle");//操作工点检周期
                if ((null != operatoninspectioncycle && operatoninspectioncycle.equals("S")) ||
                        (null != operatoninspectioncycle && operatoninspectioncycle.equals("D")) ||
                        (null != operatoninspectioncycle && operatoninspectioncycle.equals("W") ||
                                (null != operatoninspectioncycle && operatoninspectioncycle.equals("M")))) {//如果维修工点检周期是天的话，下次执行时间与当前时间相同就推送
                    insAddList.add(lubMap);
                }
            }

        }
        timeTaskToIns(insAddList, "inspectionApp");
    }

    //操作工的更新周期方法
    public void timeTaskToIns(List<Map<String, Object>> insAddList, String app) {
        //执行判空操作
        if (CollectionUtils.isNotEmpty(insAddList)) {
            //格式化日期
            String createtime = sdftime.format(new Date());

            //拿到所有新增的数据要启动流程
            StringJoiner sjNewNum = new StringJoiner("','","'","'");
            //拿到所有sql然后执行
            StringBuilder sbsql = new StringBuilder();

            for (int k = 0,size = insAddList.size(); k < size; k++) {
                //生成操作工点检编号   编号格式yyyyMMddHHmmss
                String newNum = "CZ"+fmt.format(new Date()) + String.format("%04d", k+1);
                System.out.println("编号" + newNum);
                sjNewNum.add(newNum);
                Map lubteMap = insAddList.get(k);
                String insaddId = MapUtils.getString(lubteMap, "id");
                String endtime = MapUtil.getStr(lubteMap, "endtime");//查询出点检标准中用户设置的自动关闭时间（小时制） endtime
                String insstdnum = MapUtil.getStr(lubteMap, "insstdnum");//操作工点检标准的编号
                String checkstarttime=MapUtil.getStr(lubteMap, "checkstarttime");//操作工下次开始时间
                Integer checkcycleunit = MapUtil.getInt(lubteMap, "checkcycleunit");//操作工点检周期单位
                String operatoninspectioncycle = MapUtil.getStr(lubteMap, "operatoninspectioncycle");//操作工点检周期
                //根据设置的时间进行计算 将计算好的时间存入数据库 （点检任务单的字段是任务结束时间 数据库的字段为endtime ）
                if (StringUtils.isNotEmpty(endtime)){
                    String closingtime= endTime(endtime);
                    sbsql.append("insert into bl_inspection(inspectorinspectioncycle,repairmaninspectioncycle,insstdnum,inspectionnum,inspectionname,inspectionroute,deptcode,inspectiontype,inspectiontool,keypart,inspectionstaffgroup,operatoninspectioncycle,operationstarttime,createuser,createtime,status,endtime,area) " +
                            "  select inspectorinspectioncycle,repairmaninspectioncycle,insstdnum,'" + newNum + "'as inspectionnum,insstdname as inspectionname,inspectionroute,deptcode,inspectiontype,inspectiontool,keypart,inspectionstaffgroup,operatoninspectioncycle,operationstarttime,'admin' AS createuser,'" + createtime + "' as createtime,'草稿' as status,'" + closingtime + "' as endtime,area  from bl_inspectionstandard where id ='" + insaddId + "';");
//                    sjNewNum.add(newNum);
                }else{
                    sbsql.append("insert into bl_inspection(inspectorinspectioncycle,repairmaninspectioncycle,insstdnum,inspectionnum,inspectionname,inspectionroute,deptcode,inspectiontype,inspectiontool,keypart,inspectionstaffgroup,operatoninspectioncycle,operationstarttime,createuser,createtime,status,area) " +
                            "  select inspectorinspectioncycle,repairmaninspectioncycle,insstdnum,'" + newNum + "'as inspectionnum,insstdname as inspectionname,inspectionroute,deptcode,inspectiontype,inspectiontool,keypart,inspectionstaffgroup,operatoninspectioncycle,operationstarttime,'admin' AS createuser,'" + createtime + "' as createtime,'草稿' as status ,area from bl_inspectionstandard where id ='" + insaddId + "';");
//                    sjNewNum.add(newNum);
                }


                //复制子表
                String lublineSql = "insert into bl_inspectionline(isitabnormal,inspectionassetnum,inspectionassetname,part,inspectioncontent,inspectionstandard,inspectionmethod,operatingstatus,inspectionnum,createuser,createuserdesc,createtime,deptcode)";
                String lublineSql2 = "  select 0 , inspectionassetnum,inspectionassetname,part,inspectioncontent,inspectionstandard,inspectionmethod,operatingstatus,'" + newNum + "','1','超级管理员','" + createtime + "',deptcode from bl_inspectionstandardline where insstdnum = '" + insstdnum + "';";
                sbsql.append(lublineSql + lublineSql2);

                //操作工更新周期
                if (checkstarttime != null&&checkcycleunit!=null) {
                    try {
                        Date starttime2 = sdftime.parse(checkstarttime);
                        if (null != operatoninspectioncycle && operatoninspectioncycle.equals("D")) {//更新点检周期为天的周期
                            Calendar cal = Calendar.getInstance();
                            cal.setTime(starttime2);
                            cal.add(Calendar.DAY_OF_WEEK,checkcycleunit);
                            String Nextdate = sdftime.format(cal.getTime());
                            sbsql.append("update bl_inspectionstandard set checkstarttime=DATE_FORMAT('"+Nextdate+"','%Y-%m-%d %H:%i:%s') where id ='"+insaddId+"';");
                        } else if (null != operatoninspectioncycle && operatoninspectioncycle.equals("W")) {//更新点检周期为周的周期
                            Calendar cal = Calendar.getInstance();
                            cal.setTime(starttime2);
                            cal.add(Calendar.WEEK_OF_MONTH,checkcycleunit);
                            String Nextdate = sdftime.format(cal.getTime());
                            sbsql.append("update bl_inspectionstandard set checkstarttime=DATE_FORMAT('"+Nextdate+"','%Y-%m-%d %H:%i:%s') where id ='"+insaddId +"';");
                        }else if (null != operatoninspectioncycle && operatoninspectioncycle.equals("M")) {//更新点检周期为月的周期
                            Calendar cal = Calendar.getInstance();
                            cal.setTime(starttime2);
                            cal.add(Calendar.MONTH,checkcycleunit);
                            String Nextdate = sdftime.format(cal.getTime());
                            sbsql.append("update bl_inspectionstandard set checkstarttime=DATE_FORMAT('"+Nextdate+"','%Y-%m-%d %H:%i:%s') where id ='"+insaddId +"';");
                        }

                    } catch (ParseException e) {
                        e.printStackTrace();
                        String error_log = "insert into error_log(ywid,ywtype,message,createtime) values('"+insaddId+"','更新周期','"+"更新周期异常"+"','"+createtime+"');" ;
                        sbsql.append(error_log);
                    }
                }
            }
            //执行sql
            executeSql(sbsql);
            //执行流程
            executeFlow(sjNewNum, app);
        }
    }

    public void executeSql(StringBuilder sbsql){
        // 2.获取事务定义
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        // 3.设置事务隔离级别，开启新事务
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
        // 4.获得事务状态
        TransactionStatus status = transactionManager.getTransaction(def);

        try{
            //防止内存不足
            String[] sqlss = sbsql.toString().split(";");
            StringBuilder executesbd = new StringBuilder();
            int flag = 2000;
            int i = 0;

            for(String sql : sqlss){
                executesbd.append(sql + ";");
                i++;
                if(flag == i){
                    handlerService.updateBySql(executesbd.toString());
                    executesbd.delete( 0, executesbd.length() );
                    i = 0;
                }
            }
            if(StringUtils.isNotBlank(executesbd)){
                handlerService.updateBySql(executesbd.toString());
            }
            transactionManager.commit(status);
        }catch (Exception e){
            transactionManager.rollback(status);
        }
    }

    public void executeFlow(StringJoiner sjNewNum,String app){

        List<Map<String, Object>> bySql = handlerService.findBySql("  select id from bl_inspection where inspectionnum in  (" + sjNewNum.toString() + ");");
        log.info("查询结果完成"+bySql.size());
        if(CollectionUtils.isNotEmpty(bySql)){
            log.info("进来了");
            int splitSize =  10;
            int threasize = bySql.size() / splitSize;
            if(bySql.size() < splitSize){
                threasize = 1;
            }
            //吧list分割开来  分成几个list 每个list的数量是 bySql.size() / threasize
            List<List<Map<String, Object>>> partition = ListUtils.partition(bySql, threasize);
            log.info("分裂查询结果"+partition.size());
            ExecutorService ex= Executors.newFixedThreadPool(partition.size());
            for(int i = 0, size = partition.size(); i < size; i++) {
                log.info("进入循环几个线程"+i);
                Integer finalI = i;
                ex.submit(new Runnable() {
                    @Override
                    public void run() {
                        for(Map<String, Object> map : partition.get(finalI)){
                            log.info("进入第" + finalI + "线程中 执行流程服务");
                            timeTStartFlow(MapUtils.getLongValue(map,"id"), app);
                        }
                    }
                });
            }
            ex.shutdown();
            log.info("线程停止");
        }


//        for(Map<String, Object> map : bySql){
//        }
    }

    //将点检任务的关闭时间置为   当前时间加上用户设定的时间 返回
    public String endTime(String time){
        //将传过来的参数进行转换
        Integer endtime = Integer.parseInt(time.trim());
        //java 方法中的日历类
        Calendar calendar =Calendar.getInstance();
        /* HOUR_OF_DAY 指示一天中的小时      加上传过来的几个小时*/
        calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) + endtime);
        /*获取 计算后得关闭时间*/
        Date today = calendar.getTime();
        /*设置时间格式*/
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH");
        /*转换格式*/
        String result = format.format(today);
        return result ;
    }
    /**
     * 操作工关闭定时任务推送的单据流程
     * @throws Exception
     */
    public  void byInsptaskTime() throws Exception{
        List<Object> insAddList = new ArrayList<Object>();
        //获取到当前的时间   年月日时分的形式
        SimpleDateFormat fmt1 = new SimpleDateFormat("yyyy-MM-dd HH");
        String currentDate = fmt1.format(new Date());
        //获取需关闭流程的数据
        List<Map<String, Object>> lubricantsList = handlerService.findBySql("  select id from  bl_inspection where inspectiontype='操作工点检' AND DATE_FORMAT(endtime,'%Y-%m-%d %H') = DATE_FORMAT(DATE_SUB(now(), interval 60 MINUTE),'%Y-%m-%d %H')");
        //执行判空操作
        if (lubricantsList.size()>0) {
            for (int k = 0; k < lubricantsList.size(); k++) {
                Map<String, Object> lubMap = lubricantsList.get(k);
                Integer id = MapUtil.getInt(lubMap, "id");
                //把符合关闭流程的id放到一个list里面
                insAddList.add(id);
            }
        }
        CloseTimeTaskCzg(insAddList,"inspectionApp");
    }
    //操作工的关闭流程的方法
    public  void CloseTimeTaskCzg(List<Object> insAddList, String app) {
        if (CollectionUtils.isNotEmpty(insAddList)) {
            for (int k = 0; k < insAddList.size(); k++) {
//                //获取到符合条件的操作工关闭的id
//                Integer id = (Integer) insAddList.get(k);
//                List<Map<String, Object>> lubricantsList = handlerService.findBySql("  select proc_ins_id  from  biz_flow_app  where  biz_id='"+id+"' and app='"+app+"'");
//                if (lubricantsList.size()>0){
//                    String proc_ins_id = MapUtil.getStr(lubricantsList.get(0) ,"proc_ins_id");//操作工点检关闭单据的时间
//                    workflowClient.moveManyToEnd(proc_ins_id);//关闭流程方法
                //自动关单
                try{
                    String nickname ="超级管理员";
                    String username ="admin";
                    Integer id = (Integer) insAddList.get(k);
                    FlowOpinion flowOpinion = new FlowOpinion();
                    flowOpinion.setOpinion("定时任务自动关闭");
                    flowOpinion.setOpName(nickname);
                    flowOpinion.setOpId(username);
                    flowOpinion.setFlag(true);
                    try{
                        log.info("----------------------进来了--------------------------关闭工单执行中-----");
                        handlerService.forcibleComplateTask(app,Long.valueOf(id),flowOpinion);
                        //关单完成后将关单单据的状态置为草稿
                        handlerService.findBySql(" update bl_inspection set status='草稿'  where id ='"+id+"'");
                    }catch (Exception e){
                        e.getMessage();
                    }
                }catch (Exception e){
                    log.error(e.getMessage());
                }


            }

        }
    }
    //操作工审批后将单据的状态置为完成
    @Override
    public void afterExcuteFlow(String app, Long id, FlowNode flowNode, FlowOpinion op, String event) throws Exception{
        if(flowNode.getId().equals("czgsp")){//操作工审批节点
            boolean flag = op.isFlag();//判断是否审核通过
            //审核通过的情况
            if(flag){
//                Map<String, Object> map = handlerService.findMainById(app, id);//获取操作工点检主对象
//                String inspectionnum= MapUtils.getString(map,"inspectionnum");//获取点检任务单的编号
                //更新点检任务的状态为完成
                handlerService.findBySql("update bl_inspection  set  status='完成'   where  id='"+id+"'");
            }
        }

    }
    /**
     * 操作工、点检员、维修工设置图形化界面接口
     *
     * @param app
     * @param type
     * @param params
     * @return
     * @throws Exception
     */
    @Override
    @Transactional
    public Object operate(String app, String type, Map<String, Object> params) throws Exception {
        HashMap<String, Object> result = new HashMap<String, Object>();
        result.put("resp_code", 1);
        result.put("resp_msg", "操作失败");
        if ("jockeyGraph".equalsIgnoreCase(type)) {
            //获取用户编号
            String userName = MapUtils.getString(params, "username");
            //判断前台传入的用户名参数是否为空
            if (userName != null && !"".equalsIgnoreCase(userName)) {
                //获取用户部门信息
                List<Map<String, Object>> list = handlerService.findBySql(
                        " select user.username,user.deptcode,dept.depttype,dept.pcode  from sys_user user  " +
                                " LEFT JOIN sys_dept dept on  user.deptcode=dept.code " +
                                " where user.username='" + userName + "' ");
                String deptid = MapUtils.getString(list.get(0), "deptcode"); //code
                String depttype = MapUtils.getString(list.get(0), "depttype");
                String inspectype = MapUtils.getString(params, "inspectype");// 点检类型（需前台提供参数）
                String deptname = MapUtils.getString(params, "deptname");//超链接使用参数部门名字（需前台提供参数）
                //判断前台提供的部门名字是否为空
                if (deptname != null && !"".equals(deptname)) {
                    //不为空的情况下，根据部门名字去查询code
                    List<Map<String, Object>> list1 = handlerService.findBySql("select code from  sys_dept where fullname='" + deptname + "'");
                    //超链接实际上就是阶级段划分（查看各个分厂的各个班组）
                    depttype = "3";
                    //令code的值等于deptid
                    deptid = MapUtils.getString(list1.get(0), "code");
                }
                //如果dept表中的depttype值不是1，2，3，4，110的话，就直接跳出方法
                if (!"1,2,3,4,110".contains(depttype)) {
                    return result;
                }
                String sql = "";//总的拼装sql
                //总的select
                String sql1 = "  SELECT  code,fullname,SUM(comp),SUM(ALL1),FORMAT(ifnull((SUM(COMP)/SUM(ALL1)),0)*100,2) WCL FROM ( ";
                //完成数据的select
                String sql2 = " SELECT dept.code,dept.fullname,count(inspec.id) comp,0 AS ALL1  FROM  sys_dept  dept " +
                        "  LEFT JOIN bl_inspection inspec ON  dept.code=inspec.deptcode " +
                        "  and inspec.status='完成' ";
                //全部数据的select
                String sql3 = " UNION SELECT dept.code,dept.fullname,0 as comp, count(inspec.id) AS ALL1  FROM  sys_dept  dept " +
                        "  LEFT JOIN bl_inspection inspec ON  dept.code=inspec.deptcode";
                //子查询分组条件
                String group1 = " GROUP BY dept.code,dept.fullname ";
                // 总分组条件
                String group2 = " ) A GROUP BY code ,fullname ";
                //查询条件一
                String where1 = "";
                //查询条件二
                String where2 = "";
                //根据前台传过来的点检类型进行拼装sql
                if ("操作工点检".equalsIgnoreCase(inspectype)) {//操作工点检按照每天进行完成率的统计
                    where1 = " and inspec.inspectiontype='操作工点检' and DATE_FORMAT(inspec.createtime,'%Y-%m-%d')=DATE_FORMAT(now(),'%Y-%m-%d') ";
                } else if ("维修工点检".equalsIgnoreCase(inspectype)) {//维修工点检按照每周进行完成率的统计
                    where1 = " and inspec.inspectiontype='维修工点检' and YEARWEEK(inspec.createtime,'%Y-%m-%d') = YEARWEEK(now()) ";
                } else if ("点检员点检".equalsIgnoreCase(inspectype)) {//点检员点检按照每月进行完成率的统计
                    where1 = " and inspec.inspectiontype='点检员点检' and DATE_FORMAT(inspec.createtime,'%Y-%m')=DATE_FORMAT(now(),'%Y-%m') ";
                }
                if ("1".equalsIgnoreCase(depttype)) {//总公司
                    where2 = "WHERE dept.depttype=3 ";
                    sql2 = " SELECT dept.code,dept.fullname,count(inspec.id) comp,0 AS ALL1  FROM  sys_dept  dept " +
                            "  LEFT JOIN bl_inspection inspec ON  left(dept.code,6)=left(inspec.deptcode,6) " +
                            "  and inspec.status='完成' ";
                    sql3 = " UNION SELECT dept.code,dept.fullname,0 as comp, count(inspec.id) AS ALL1  FROM  sys_dept  dept " +
                            "  LEFT JOIN bl_inspection inspec ON  left(dept.code,6)=left(inspec.deptcode,6)";
                } else if ("2".equalsIgnoreCase(depttype) || "110".equalsIgnoreCase(depttype)) {//装备能源部，包铝集团，华云新材料等公司
                    where2 = "WHERE dept.depttype=3  ";
                    sql2 = " SELECT dept.code,dept.fullname,count(inspec.id) comp,0 AS ALL1  FROM  sys_dept  dept " +
                            "  LEFT JOIN bl_inspection inspec ON  left(dept.code,6)=left(inspec.deptcode,6) " +
                            "  and inspec.status='完成' ";
                    sql3 = " UNION SELECT dept.code,dept.fullname,0 as comp, count(inspec.id) AS ALL1  FROM  sys_dept  dept " +
                            "  LEFT JOIN bl_inspection inspec ON  left(dept.code,6)=left(inspec.deptcode,6)";
                } else if ("3".equalsIgnoreCase(depttype)) {//各个分厂（比如电解二厂等）
//                    where2 = "WHERE dept.pcode='" + deptid + "'";
                    where2 = "where dept.depttype in ('4','5') and left(dept.CODE,6)= left('"+deptid+"',6)";

                } else  {//车间
//                    if ("4".equalsIgnoreCase(depttype))
                    where2 = "WHERE dept.code='" + deptid + "'";
                }
                //总的拼装sql
                sql = sql1 + sql2 + where1 + where2 + group1 + sql3 + where1 + where2 + group1 + group2;
                List<Map<String, Object>> powerList = handlerService.findBySql(sql);
                //pc端数据的返回情况
                Map<String, Object> resultMap = new HashMap<String, Object>();
                List<Object> resuleList1 = new ArrayList<Object>();
                List<Object> resuleList2 = new ArrayList<Object>();
                for (int i = 0; i < powerList.size(); i++) {
                    resuleList1.add(powerList.get(i).get("fullname"));
                    resuleList2.add(powerList.get(i).get("WCL"));
                }
                resultMap.put("fullname", resuleList1);
                resultMap.put("completionrate", resuleList2);
                return resultMap;
//                移动端可能会用到以下接口的返回格式
//                List<Object> resuleList = new ArrayList<Object>();
//                for(int i=0;i<powerList.size();i++){
//                    HashMap<String,Object> resultMap=new HashMap<String, Object>() ;
//                    resultMap.put("name",MapUtils.getString(powerList.get(i),"fullname"));
//                    resultMap.put("data",MapUtils.getDouble(powerList.get(i),"WCL"));
//                    resuleList.add(resultMap);
//                }
//                result.put("series",resuleList);
//                result.put("resp_code",0);
//                result.put("resp_msg","操作成功");
//                return result;
            }
        }
        return result;
    }
    @Override
    public void afterSave(String app, String objName, Map<String, Object> data, boolean isUpdate) throws Exception {
        //根据点检子表的异常情况 生成缺陷提报单
        if ("bl_inspection".equalsIgnoreCase(objName)) {
            String inspectionnum = MapUtils.getString(data, "inspectionnum");
            List<Map<String, Object>> list = handlerService.findBySql("select * from bl_inspectionline where inspectionnum='" + inspectionnum + "'" + "and isitabnormal=1  and flag  is null ");
            String deptcode = MapUtils.getString(data, "deptcode");
            String area = MapUtils.getString(data, "area");

            LoginAppUser loginAppUser = SysUserUtil.getLoginAppUser();
//            String username="104000150";
            String username = loginAppUser.getId().toString();
            String nickname = loginAppUser.getNickname();
            if (!list.isEmpty() && list.size() > 0) {
                for (int i = 0; i < list.size(); i++) {
                    String reportnum = handlerService.findBizNum("defectreportApp", "bl_defectreport");
                    String id = MapUtils.getString(list.get(i), "id");
                    handlerService.findBySql("INSERT into bl_defectreport(reportnum,reportname,apptype,assetnum,finddate,status,deptcode,createuser,createtime,isnoworker,type,area) " +
                            "    (select '" + reportnum + "' as reportnum, CONCAT(ifnull(inspectionassetname,''),ifnull(part,''),ifnull(inspectioncontent,''),'异常') as reportname,  " +
                            " '提报' as apptype,inspectionassetnum as assetnum ,now() as finddate, '草稿' as status, '" + deptcode + "' AS deptcode, " +
                            " '" + username + "' as createuser,now() as createtime ,'是','否' ,"+area+" " +
                            " from bl_inspectionline where id='" + id + "'); ");
                    handlerService.updateBySql("UPDATE    bl_inspectionline set flag=1 where id='" + id + "'");
                    // 启动缺陷提报单流程
                    List<Map<String, Object>> reportlist = handlerService.findBySql
                            ("select id from bl_defectreport where reportnum='" + reportnum + "' ");//获取缺陷提报单id
                    Long reportID = MapUtils.getLong(reportlist.get(0), "id");
                    FlowOpinion flowOpinion = new FlowOpinion();
                    flowOpinion.setOpId(username);
                    flowOpinion.setOpName(nickname);
                    try {
                        handlerService.forcibleStart("defectreportApp", reportID, flowOpinion);
                    } catch (Exception e) {
                    }
                }


            }

        }

        super.afterSave(app, objName, data, isUpdate);
    }
}






